package com.wiscamp.ninechapters.panels.adapter.resources;

import com.wiscamp.ninechapters.panels.application.command.BindUnbindRoleMenuCommand;
import com.wiscamp.ninechapters.panels.application.command.BindUnbindRolePermissionCommand;
import com.wiscamp.ninechapters.panels.application.command.CreateRoleCommand;
import com.wiscamp.ninechapters.panels.application.command.UpdateRoleCommand;
import com.wiscamp.ninechapters.panels.application.services.RoleAppService;
import com.wiscamp.ninechapters.panels.application.vo.MenuVO;
import com.wiscamp.ninechapters.panels.application.vo.PermissionVO;
import com.wiscamp.ninechapters.panels.application.vo.RoleVO;
import cube.ddd.adapter.BaseController;
import cube.ddd.adapter.RestResponse;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.application.command.DisableCommand;
import cube.ddd.application.command.EnableCommand;
import cube.ddd.aspect.HandleResourceException;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.ResourceUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.core.Context;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

/**
 * 角色服务端点
 *
 * @author yifeng
 */
@RestController
@RequestMapping("/api/ControlPanels")
@Tag(name = "控制面板-角色信息")
public class RoleController extends BaseController {

    private final RoleAppService roleAppService;

    public RoleController(RoleAppService roleAppService) {
        this.roleAppService = roleAppService;
    }

    @GetMapping("Roles/{roleId}")
    @Operation(summary = "通过编号获取角色")
    @HandleResourceException
    public RestResponse<RoleVO> getRole(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                        @PathVariable("roleId") long roleId) {
        return ResourceUtils.getById(request, response, roleId, roleAppService::getRole);
    }


    @GetMapping("Applications/{appId}/Roles/Code/{roleCode}")
    @Operation(summary = "通过代码获取角色")
    @HandleResourceException
    public RestResponse<RoleVO> getRoleByCode(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                              @PathVariable("appId") long appId, @PathVariable("roleCode") String roleCode) {
        return ResourceUtils.getByIdAndText(request, response, appId, roleCode, roleAppService::getRoleByCode);
    }

    @GetMapping("Applications/{appId}/Roles/Name/{roleName}")
    @Operation(summary = "通过名称获取角色列表")
    @HandleResourceException
    public RestResponse<Collection<RoleVO>> getRolesByName(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                           @PathVariable("appId") long appId, @PathVariable("roleName") String roleName) {
        return ResourceUtils.getListByIdAndText(request, response, appId, roleName, roleAppService::getRolesByName);
    }

    @GetMapping("Applications/{appId}/Roles/Available")
    @Operation(summary = "获取可用角色列表")
    @HandleResourceException
    public RestResponse<Collection<RoleVO>> getAvailableRoles(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                              @PathVariable("appId") long appId) {
        return ResourceUtils.getListById(request, response, appId, roleAppService::getAvailableRoles);
    }

    @PostMapping("Roles/Query")
    @Operation(summary = "分页获取角色列表")
    @HandleResourceException
    public RestResponse<Collection<RoleVO>> getRolesByQuery(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                            @RequestBody PagedQuery query) {
        return ResourceUtils.getPagedObjectsByQuery(request, response, query, roleAppService::getRolesByQuery);
    }

    @GetMapping("Roles/{roleId}/Menus")
    @Operation(summary = "通过编号获取角色关联的菜单")
    @HandleResourceException
    public RestResponse<Collection<MenuVO>> getMenusByRole(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                           @PathVariable("roleId") long roleId) {
        return ResourceUtils.getById(request, response, roleId, roleAppService::getMenusByRole);
    }

    @GetMapping("Roles/{roleId}/Permissions")
    @Operation(summary = "通过编号获取角色关联的权限")
    @HandleResourceException
    public RestResponse<Collection<PermissionVO>> getPermissionsByRole(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                       @PathVariable("roleId") long roleId) {
        return ResourceUtils.getById(request, response, roleId, roleAppService::getPermissionsByRole);
    }


    @PostMapping("Roles")
    @Operation(summary = "创建角色")
    @HandleResourceException
    public RestResponse<RoleVO> createRole(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody CreateRoleCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, roleAppService::createRole);
    }


    @PutMapping("Roles")
    @Operation(summary = "更新角色")
    @HandleResourceException
    public RestResponse<RoleVO> updateRole(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody UpdateRoleCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, roleAppService::updateRole);
    }

    @PutMapping("Roles/Actions/Delete")
    @Operation(summary = "通过编号删除角色")
    @HandleResourceException
    public RestResponse<Boolean> deleteRole(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody DeleteCommand command) {
        return ResourceUtils.delete(request, response, command, roleAppService::deleteRole);
    }

    @PutMapping("Roles/Actions/Enable")
    @Operation(summary = "通过编号启用角色")
    @HandleResourceException
    public RestResponse<Boolean> enableRole(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody EnableCommand command) {
        return ResourceUtils.enable(request, response, command, roleAppService::enableRole);
    }

    @PutMapping("Roles/Actions/Disable")
    @Operation(summary = "通过编号禁用角色")
    @HandleResourceException
    public RestResponse<Boolean> disableRole(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody DisableCommand command) {
        return ResourceUtils.disable(request, response, command, roleAppService::disableRole);
    }

    @PostMapping("Roles/Actions/Bind/Menu")
    @Operation(summary = "绑定角色菜单关系")
    @HandleResourceException
    public RestResponse<Boolean> bindRoleMenu(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody BindUnbindRoleMenuCommand command) {
        var success = roleAppService.bindRoleMenu(command);
        return ResourceUtils.getOkResponse(request, response, success);
    }

    @PostMapping("Roles/Actions/Unbind/Menu")
    @Operation(summary = "解绑角色菜单关系")
    @HandleResourceException
    public RestResponse<Boolean> unbindRoleMenu(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody BindUnbindRoleMenuCommand command) {
        var success = roleAppService.unbindRoleMenu(command);
        return ResourceUtils.getOkResponse(request, response, success);
    }

    @PostMapping("Roles/Actions/Bind/Permission")
    @Operation(summary = "绑定角色权限关系")
    @HandleResourceException
    public RestResponse<Boolean> bindRolePermission(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody BindUnbindRolePermissionCommand command) {
        var success = roleAppService.bindRolePermission(command);
        return ResourceUtils.getOkResponse(request, response, success);
    }

    @PostMapping("Roles/Actions/Unbind/Permission")
    @Operation(summary = "解绑角色权限关系")
    @HandleResourceException
    public RestResponse<Boolean> unbindRolePermission(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody BindUnbindRolePermissionCommand command) {
        var success = roleAppService.unbindRolePermission(command);
        return ResourceUtils.getOkResponse(request, response, success);
    }
}
